package com.sherllinhe.business.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.ObjUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
//import com.sherllinhe.common.context.LoginMemberContext;
import com.sherllinhe.business.domain.*;
import com.sherllinhe.business.enums.SeatColEnum;
import com.sherllinhe.business.enums.SeatTypeEnum;
import com.sherllinhe.business.enums.TrainTypeEnum;
import com.sherllinhe.common.resp.PageResp;
import com.sherllinhe.common.util.SnowUtil;
import com.sherllinhe.business.mapper.DailyTrainTicketMapper;
import com.sherllinhe.business.req.DailyTrainTicketQueryReq;
import com.sherllinhe.business.req.DailyTrainTicketSaveReq;
import com.sherllinhe.business.resp.DailyTrainTicketQueryResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;

/**
 * 功能：
 * 作者：Sherllin He
 * 日期：
 */
@Slf4j
@Service
public class DailyTrainTicketService {
    @Autowired
    private DailyTrainTicketMapper dailyTrainTicketMapper;
    @Autowired
    private TrainStationService trainStationService;
    @Autowired
    private DailyTrainSeatService dailyTrainSeatService;
    // 新增和编辑余票信息
    public void save(DailyTrainTicketSaveReq req){
        DateTime now = DateTime.now();
        DailyTrainTicket dailyTrainTicket = BeanUtil.copyProperties(req, DailyTrainTicket.class);

        //判断是新增还是更新
        //dailyTrainTicket.setMemberId(LoginMemberContext.getId());
        if(ObjUtil.isNull(dailyTrainTicket.getId())) {
            //新增
            dailyTrainTicket.setId(SnowUtil.getSnowflakeNextId());
            dailyTrainTicket.setCreateTime(now);
            dailyTrainTicket.setUpdateTime(now);
            dailyTrainTicketMapper.insert(dailyTrainTicket);
        }else{
            //更新
            dailyTrainTicket.setUpdateTime(now);
            dailyTrainTicketMapper.updateByPrimaryKey(dailyTrainTicket);
        }


    }
    //CachePut注解会去数据库查然后更新缓存，无论缓存中有没有值，都会去数据库查询
    @CachePut(value = "DailyTrainTicketService.queryList")
    public PageResp<DailyTrainTicketQueryResp> queryList2(DailyTrainTicketQueryReq req){
        return queryList(req);
    }
    // 分页查询余票信息列表
    // Cacheable注解会去缓存中查询，如果缓存中有值，则直接返回缓存中的值，不会去数据库查询
//    @Cacheable(value = "DailyTrainTicketService.queryList")
    public PageResp<DailyTrainTicketQueryResp> queryList(DailyTrainTicketQueryReq req){
        DailyTrainTicketExample example = new DailyTrainTicketExample();
        example.setOrderByClause("train_code asc, start_index asc, end_index asc");
        DailyTrainTicketExample.Criteria criteria = example.createCriteria();
        //if(ObjUtil.isNotNull(req.getMemberId())){
            //criteria.andMemberIdEqualTo(req.getMemberId());
        //}
        if(ObjUtil.isNotEmpty(req.getTrainCode())){
            criteria.andTrainCodeEqualTo(req.getTrainCode());
        }
        if (ObjUtil.isNotNull(req.getDate())){
            criteria.andDateEqualTo(req.getDate());
        }
        if (ObjUtil.isNotEmpty(req.getStart())){
            criteria.andStartEqualTo(req.getStart());
        }
        if (ObjUtil.isNotEmpty(req.getEnd())){
            criteria.andEndEqualTo(req.getEnd());
        }

        log.info("查询页码:{}",req.getPage());
        log.info("每页条数:{}",req.getSize());
        PageHelper.startPage(req.getPage(),req.getSize());
        List<DailyTrainTicket> dailyTrainTicketList = dailyTrainTicketMapper.selectByExample(example);

        PageInfo<DailyTrainTicket> pageInfo = new PageInfo<>(dailyTrainTicketList);
        log.info("总条数:{}", pageInfo.getTotal());
        log.info("总页数:{}", pageInfo.getPages());

        List<DailyTrainTicketQueryResp> list = BeanUtil.copyToList(dailyTrainTicketList, DailyTrainTicketQueryResp.class);

        PageResp<DailyTrainTicketQueryResp> pageResp = new PageResp<>();
        pageResp.setList(list);
        pageResp.setTotal(pageInfo.getTotal());

        return pageResp;
    }
    //删除余票信息
    public void delete(Long id){
        dailyTrainTicketMapper.deleteByPrimaryKey(id);
    }

    @Transactional
    public void genDailyTicket(Train train, Date date, String trainCode){
        log.info("生成日期【{}】车次【{}】的余票信息开始", DateUtil.formatDate(date), trainCode);
        // 删除某日某车次的余票信息
        DailyTrainTicketExample dailyTrainTicketExample = new DailyTrainTicketExample();
        dailyTrainTicketExample.createCriteria()
                .andDateEqualTo(date)
                .andTrainCodeEqualTo(trainCode);
        dailyTrainTicketMapper.deleteByExample(dailyTrainTicketExample);

        //查询途径的车站信息
        List<TrainStation> trainStationList = trainStationService.selectByUnique(trainCode);
        if(CollUtil.isEmpty(trainStationList)){
            log.info("该车次没有车站基础数据，生成该车次的余票信息结束");
            return;
        }

        // 插入数据
        int ydz = dailyTrainSeatService.countSeat(date, trainCode, SeatTypeEnum.YDZ.getCode());
        int edz = dailyTrainSeatService.countSeat(date, trainCode, SeatTypeEnum.EDZ.getCode());
        int yw = dailyTrainSeatService.countSeat(date, trainCode, SeatTypeEnum.YW.getCode());
        int rw = dailyTrainSeatService.countSeat(date, trainCode, SeatTypeEnum.RW.getCode());
        for (int i = 0; i < trainStationList.size() ; i++) {
            //得到出发站
            TrainStation trainStationStart = trainStationList.get(i);
            DateTime now = DateTime.now();
            BigDecimal sumKm = BigDecimal.ZERO;
            for (int j = (i + 1); j < trainStationList.size(); j++) {
                TrainStation trainStationEnd = trainStationList.get(j);
                DailyTrainTicket dailyTrainTicket = new DailyTrainTicket();

                sumKm = sumKm.add(trainStationEnd.getKm());
                String trainType = train.getType();
                BigDecimal  priceRate = EnumUtil.getFieldBy(TrainTypeEnum::getPriceRate, TrainTypeEnum::getCode, trainType);
                BigDecimal ydzPrice = sumKm.multiply(SeatTypeEnum.YDZ.getPrice()).multiply(priceRate).setScale(2, RoundingMode.HALF_UP);
                BigDecimal edzPrice = sumKm.multiply(SeatTypeEnum.EDZ.getPrice()).multiply(priceRate).setScale(2, RoundingMode.HALF_UP);
                BigDecimal ywPrice = sumKm.multiply(SeatTypeEnum.YW.getPrice()).multiply(priceRate).setScale(2, RoundingMode.HALF_UP);
                BigDecimal rwPrice = sumKm.multiply(SeatTypeEnum.RW.getPrice()).multiply(priceRate).setScale(2, RoundingMode.HALF_UP);

                dailyTrainTicket.setId(SnowUtil.getSnowflakeNextId());
                dailyTrainTicket.setDate(date);
                dailyTrainTicket.setTrainCode(trainCode);
                dailyTrainTicket.setStart(trainStationStart.getName());
                dailyTrainTicket.setStartPinyin(trainStationStart.getNamePinyin());
                dailyTrainTicket.setStartTime(trainStationStart.getOutTime());
                dailyTrainTicket.setStartIndex(trainStationStart.getIndex());
                dailyTrainTicket.setEnd(trainStationEnd.getName());
                dailyTrainTicket.setEndPinyin(trainStationEnd.getNamePinyin());
                dailyTrainTicket.setEndTime(trainStationEnd.getInTime());
                dailyTrainTicket.setEndIndex(trainStationEnd.getIndex());
                dailyTrainTicket.setYdz(ydz);
                dailyTrainTicket.setYdzPrice(ydzPrice);
                dailyTrainTicket.setEdz(edz);
                dailyTrainTicket.setEdzPrice(edzPrice);
                dailyTrainTicket.setRw(rw);
                dailyTrainTicket.setRwPrice(rwPrice);
                dailyTrainTicket.setYw(yw);
                dailyTrainTicket.setYwPrice(ywPrice);
                dailyTrainTicket.setCreateTime(now);
                dailyTrainTicket.setUpdateTime(now);

                dailyTrainTicketMapper.insert(dailyTrainTicket);
            }
        }

        log.info("生成日期【{}】车次【{}】的车站信息结束", DateUtil.formatDate(date), trainCode);
    }

    //  查询唯一键
    public DailyTrainTicket selectByUnique(Date date,String trainCode,String start,String end) {
        DailyTrainTicketExample  example = new DailyTrainTicketExample();
        example.createCriteria().andTrainCodeEqualTo(trainCode).andDateEqualTo(date)
                .andStartEqualTo(start).andEndEqualTo(end);
        List<DailyTrainTicket> list = dailyTrainTicketMapper.selectByExample(example);
        if(CollUtil.isNotEmpty(list)){
            return list.get(0);
        }else {
            return null;
        }
    }
}
